home *** CD-ROM | disk | FTP | other *** search
/ 17 Bit Software 6: Level 6 / 17 Bit - Level 6 (1998)(Epic Marketing)[!].iso / quartz / q1082.dms / q1082.adf / src.lzh / Fig / addpt.c next >
C/C++ Source or Header  |  1991-07-18  |  7KB  |  294 lines

  1. /* 
  2.  *    FIG : Facility for Interactive Generation of figures
  3.  *
  4.  *    Copyright (c) 1985 by Supoj Sutanthavibul (supoj@sally.UTEXAS.EDU)
  5.  *    January 1985.
  6.  *    1st revision : August 1985.
  7.  *    2nd revision : March 1988.
  8.  *
  9.  *    %W%    %G%
  10. */
  11. #include "fig.h"
  12. #include "resources.h"
  13. #include "alloc.h"
  14. #include "func.h"
  15. #include "object.h"
  16. #include "paintop.h"
  17.  
  18. #define            TOLERANCE    3
  19.  
  20. extern F_line        *line_search();
  21. extern F_spline        *spline_search();
  22. extern            (*canvas_kbd_proc)();
  23. extern            (*canvas_locmove_proc)();
  24. extern            (*canvas_leftbut_proc)();
  25. extern            (*canvas_middlebut_proc)();
  26. extern            (*canvas_rightbut_proc)();
  27. extern            null_proc();
  28. extern            set_popupmenu();
  29.  
  30. extern int        cur_x, cur_y;
  31. extern int        pointmarker_shown;
  32. extern F_line        *line;
  33. extern F_spline        *spline;
  34.  
  35. extern F_point        *added_point;
  36. extern F_point        *left_point, *right_point;
  37.  
  38.             init_point_adding();
  39.             move_addedpoint();
  40.             fix_linepoint_adding();
  41.             fix_splinepoint_adding();
  42.  
  43. static F_line        *cur_line;
  44. static F_spline        *cur_spline;
  45.  
  46. point_adding_selected()
  47. {
  48.     canvas_kbd_proc = null_proc;
  49.     canvas_locmove_proc = null_proc;
  50.     canvas_leftbut_proc = init_point_adding;
  51.     canvas_middlebut_proc = null_proc;
  52.     canvas_rightbut_proc = set_popupmenu;
  53.     set_cursor(&pick9_cursor);
  54.     }
  55.  
  56. init_point_adding(x, y)
  57. int    x, y;
  58. {
  59.     int    px, py;
  60.  
  61.     if ((cur_line = line_search(x, y, TOLERANCE, &px, &py)) != NULL) {
  62.         if (cur_line->type == T_BOX) {
  63.         put_msg("Adding points to a box is not allowed");
  64.         return;
  65.         }
  66.         init_linepointadding(px, py);
  67.         }
  68.     else if ((cur_spline = spline_search(x,y,TOLERANCE,&px,&py)) != NULL){
  69.         init_splinepointadding(px, py);
  70.         }
  71.     else {
  72.         return;
  73.         }
  74.     canvas_leftbut_proc = canvas_rightbut_proc = null_proc;
  75.     erase_pointmarker();
  76.     }
  77.  
  78. wrapup_pointadding()
  79. {
  80.     show_pointmarker();
  81.     point_adding_selected();
  82.     }
  83.  
  84. /**************************  spline  *******************************/
  85.  
  86. init_splinepointadding(px, py)
  87. int        px, py;
  88. {
  89.     find_endpoints(cur_spline->points, px, py, &left_point, &right_point);
  90.     set_temp_cursor(&null_cursor);
  91.     win_setmouseposition(canvas_swfd, px, py);
  92.     cur_x = px; cur_y = py;
  93.     if (left_point == NULL && closed_spline(cur_spline)) {
  94.         /* The added_point is between the 1st and 2nd point. */
  95.         left_point = right_point;
  96.         right_point = right_point->next;
  97.         }
  98.     draw_addedlink(INV_PAINT);
  99.     canvas_locmove_proc = move_addedpoint;
  100.     canvas_middlebut_proc = fix_splinepoint_adding;
  101.     }
  102.  
  103. fix_splinepoint_adding(x, y)
  104. int    x, y;
  105. {
  106.     F_point        *p;
  107.  
  108.     if (NULL == (Point_malloc(p))) {
  109.         put_msg(Err_mem);
  110.         wrapup_pointadding();
  111.         return;
  112.         }
  113.     clean_up();
  114.     added_point = p;
  115.     added_point->x = x;
  116.     added_point->y = y;
  117.     draw_addedlink(INV_PAINT);
  118.     if (-1 == splinepoint_adding(cur_spline, added_point))
  119.         wrapup_pointadding();
  120.     set_action_object(F_ADD_POINT, O_SPLINE);
  121.     set_latestspline(cur_spline);
  122.     wrapup_pointadding();
  123.     }
  124.  
  125. /*
  126. Warning: Do not change the value of the pointers left_point and
  127. right_point.  Added_point is always inserted between left_point
  128. and right_point, except in two cases. 
  129.     (1) left_point is NULL, the added_point will be prepended
  130.         to the list of points. This case will never
  131.         occur if the spline is closed (periodic).
  132.     (2) right_point is NULL, the added_point will be appended
  133.         to the end of the list.
  134. */
  135.  
  136. splinepoint_adding(spline, added_point)
  137. F_spline    *spline;
  138. F_point        *added_point;
  139. {
  140.     F_control    *c;
  141.  
  142.     set_temp_cursor(&wait_cursor);
  143.     if (int_spline(spline)) {    /* Interpolated spline */
  144.         if (NULL == (Control_malloc(c))) {
  145.         put_msg(Err_mem);
  146.         return(-1);
  147.         }
  148.         }
  149.     pw_batch_on(canvas_pixwin);
  150.     if (pointmarker_shown) toggle_splinepointmarker(spline);  
  151.     draw_spline(spline, ERASE); /* erase old spline */
  152.     if (left_point == NULL) {
  153.         added_point->next = spline->points;
  154.         spline->points = added_point;
  155.         }
  156.     else {
  157.         added_point->next = right_point;
  158.         left_point->next = added_point;
  159.         }
  160.  
  161.     if (int_spline(spline)) {    /* Interpolated spline */
  162.         c->next = spline->controls;
  163.         spline->controls = c;
  164.         remake_control_points(spline);
  165.         }
  166.  
  167.     draw_spline(spline, PAINT); /* draw the modified spline */
  168.     if (pointmarker_shown) toggle_splinepointmarker(spline);  
  169.     pw_batch_off(canvas_pixwin);
  170.     reset_cursor();
  171.     set_modifiedflag();
  172.     return(1);
  173.     }
  174.  
  175. /***************************  line  ********************************/
  176.  
  177. init_linepointadding(px, py)
  178. int    px, py;
  179. {
  180.     find_endpoints(cur_line->points,px,py,&left_point,&right_point);
  181.     set_temp_cursor(&null_cursor);
  182.     win_setmouseposition(canvas_swfd, px, py);
  183.     cur_x = px; cur_y = py;
  184.     if (left_point == NULL && cur_line->type == T_POLYGON) {
  185.         left_point = right_point;
  186.         right_point = right_point->next;
  187.         }
  188.     if (left_point != NULL && right_point != NULL)
  189.         draw_line_segment(cur_line->style, cur_line->style_val,
  190.         left_point->x, left_point->y,
  191.         right_point->x, right_point->y, INV_PAINT);
  192.     draw_addedlink(INV_PAINT);
  193.     canvas_locmove_proc = move_addedpoint;
  194.     canvas_middlebut_proc = fix_linepoint_adding;
  195.     }
  196.  
  197. fix_linepoint_adding(x, y)
  198. int    x, y;
  199. {
  200.     F_point        *p;
  201.  
  202.     if (NULL == (Point_malloc(p))) {
  203.         put_msg(Err_mem);
  204.         wrapup_pointadding();
  205.         return;
  206.         }
  207.     clean_up();
  208.     added_point = p;
  209.     added_point->x = x;
  210.     added_point->y = y;
  211.     draw_addedlink(INV_PAINT);
  212.     linepoint_adding(cur_line, added_point);
  213.     set_action_object(F_ADD_POINT, O_POLYLINE);
  214.     set_latestline(cur_line);
  215.     wrapup_pointadding();
  216.     }
  217.  
  218. linepoint_adding(line, added_point)
  219. F_line    *line;
  220. F_point    *added_point;
  221. {
  222.     if (pointmarker_shown) toggle_linepointmarker(line);
  223.     draw_line(line, ERASE);
  224.     if (left_point == NULL) {
  225.         added_point->next = line->points;
  226.         line->points = added_point;
  227.         }
  228.     else {
  229.         added_point->next = left_point->next;
  230.         left_point->next = added_point;
  231.         }
  232.     draw_line(line, PAINT);
  233.     if (pointmarker_shown) toggle_linepointmarker(line);  
  234.     set_modifiedflag();
  235.     }
  236.  
  237. /*******************************************************************/
  238.  
  239. /*
  240. If (x,y) is close to a point, q, fp points to q and sp points to q->next
  241. (right).  However if q is the first point, fp contains NULL and sp points to q.
  242. */
  243.  
  244. find_endpoints(p, x, y, fp, sp)
  245. F_point    *p, **fp, **sp;
  246. int    x, y;
  247. {
  248.     int    d;
  249.     F_point    *a = NULL, *b = p;
  250.  
  251.     if (x == b->x && y == b->y) {
  252.         *fp = a;
  253.         *sp = b;
  254.         return;
  255.         }
  256.  
  257.     for (a = p, b = p->next; b != NULL; a = b, b = b->next){
  258.         if (x == b->x && y == b->y) {
  259.         *fp = b;
  260.         *sp = b->next;
  261.         return;
  262.         }
  263.         if (close_to_vector(a->x, a->y, b->x, b->y, x, y, 1, 1.0, &d, &d)) {
  264.         *fp = a;
  265.         *sp = b;
  266.         return;
  267.         }
  268.         }
  269.     *fp = a;
  270.     *sp = b;
  271.     }
  272.  
  273. draw_addedlink(op)
  274. int    op;
  275. {
  276.     if (left_point != NULL) {
  277.         pw_vector(canvas_pixwin, left_point->x, left_point->y,
  278.             cur_x, cur_y, op, 1);
  279.        }
  280.     if (right_point != NULL) {
  281.         pw_vector(canvas_pixwin, right_point->x, 
  282.             right_point->y, cur_x, cur_y, op, 1);
  283.         }
  284.     }
  285.  
  286. move_addedpoint(x, y)
  287. int    x, y;
  288. {
  289.     draw_addedlink(INV_PAINT);
  290.     cur_x = x;
  291.     cur_y = y;
  292.     draw_addedlink(INV_PAINT);
  293.     }
  294.